﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TjZheng.Framework;
using TjZheng.Power.Business;
using TjZheng.Power.DataEntity;
using TjZheng.Base;
using TjZheng.Redis;
using TjZheng.Power.RedisEntity;

namespace TjZheng.CMS.Process.Business
{
    /// <summary>
    /// 权限处理器
    /// </summary>
    public partial class PowerProcess
    {
        /// <summary>
        /// 是否从Redis检查用户权限
        /// </summary>
        protected bool IsCheckUserPowerRedis
        {
            get
            {
                return ConfigHelper.GetBoolValue("IsCheckUserPowerRedis", true);
            }
        }
        /// <summary>
        /// 快速添加-保存
        /// </summary>
        /// <param name="powerId"></param>
        /// <param name="buttonIds"></param>
        /// <param name="controllerName"></param>
        /// <returns></returns>
        public InvokeResult AddPowers(long powerId, string buttonIds, string controllerName, string areaName = "")
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (buttonIds.IsNull())
            {
                objInvokeResult.ResultCode = "ButtonIdsNull";
                objInvokeResult.ResultMessage = "请先选择一条数据";
                return objInvokeResult;
            }
            if (controllerName.IsNull())
            {
                objInvokeResult.ResultCode = "ControllerNameNull";
                objInvokeResult.ResultMessage = "请输入控制器名称";
                return objInvokeResult;
            }
            BizPowerInfo objBizPowerInfo = new BizPowerInfo();
            var objParent = objBizPowerInfo.GetRecord(powerId);
            if (objParent == null)
            {
                objInvokeResult.ResultCode = "PowerInfoParentNull";
                objInvokeResult.ResultMessage = "父权限不存在";
                return objInvokeResult;
            }
            BizButtonInfo objBizButtonInfo = new BizButtonInfo();
            var objButtionInfoList = objBizButtonInfo.GetList(buttonIds.FormatSelf("Id in({0})"));
            if (objButtionInfoList.IsNull())
            {
                objInvokeResult.ResultCode = "ButtonsNull";
                objInvokeResult.ResultMessage = "请先选择一条数据";
                return objInvokeResult;
            }
            int result = 0;
            objBizPowerInfo.ExecuteTransation(() =>
            {
                List<PowerInfo> objUpdates = new List<PowerInfo>();
                foreach (var objButtonInfo in objButtionInfoList.OrderBy(c => c.SortIndex))
                {
                    var objChild = new PowerInfo
                    {
                        PowerName = objButtonInfo.ButtonName,
                        PowerCode = Guid.NewGuid().ToString(),
                        ParentId = objParent.Id,
                        AreaName = objButtonInfo.IsWriteControllerName == 1 ? areaName : "",
                        ControllerName = objButtonInfo.IsWriteControllerName == 1 ? controllerName : "",
                        ActionName = objButtonInfo.DefaultActionName,
                        PowerType = 2,
                        Position = objButtonInfo.DefaultPosition,
                        Execution = objButtonInfo.DefaultExecution,
                        Icon = objButtonInfo.Icon,
                        IsDisplay = 1,
                        Depth = objParent.Depth + 1,
                        CreateDate = DateTime.Now
                    };
                    objChild.Id = objBizPowerInfo.Add(objChild);
                    objChild.IDPath = objParent.IDPath + objChild.Id + ",";
                    objChild.SortIndex = objChild.Id;
                    objChild.SetState(EntityStatus.Modified);
                    objUpdates.Add(objChild);
                }
                if (objParent.HasChild != 1)
                {
                    objParent.HasChild = 1;
                    objParent.SetState(EntityStatus.Modified);
                    objUpdates.Add(objParent);
                }
                result = objBizPowerInfo.Batch(objUpdates, false);

                if (IsCheckUserPowerRedis)
                {
                    objBizPowerInfo.StoreAll(objUpdates, PowerVariable.ProviderName, PowerVariable.Db);
                }
            });
            if (result < 0)
            {
                objInvokeResult.ResultCode = "AddPowersFailed";
                objInvokeResult.ResultMessage = "快速添加失败";
                return objInvokeResult;
            }
            objInvokeResult.ResultMessage = "快速添加成功";
            return objInvokeResult;
        }
        /// <summary>
        /// 权限排序-保存
        /// </summary>
        /// <param name="powerIds"></param>
        /// <returns></returns>
        public InvokeResult SaveSort(string powerIds)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (powerIds.IsNull())
            {
                objInvokeResult.ResultCode = "PowerIdsNull";
                objInvokeResult.ResultMessage = "请选择排序";
                return objInvokeResult;
            }
            BizPowerInfo objBizPowerInfo = new BizPowerInfo();
            var objPowerInfoList = objBizPowerInfo.GetList(powerIds.FormatSelf("Id in({0})"));
            if (objPowerInfoList.IsNull())
            {
                objInvokeResult.ResultCode = "PowersNull";
                objInvokeResult.ResultMessage = "请选择排序";
                return objInvokeResult;
            }
            int i = 0;
            List<long> objSoftIndexs = objPowerInfoList.Select(c => c.SortIndex).OrderBy(c => c).ToList();
            foreach (var powerId in powerIds.Split(',').Select(c => long.Parse(c)))
            {
                var objPowerInfo = objPowerInfoList.FirstOrDefault(c => c.Id == powerId);
                if (objPowerInfo != null)
                {
                    if (objPowerInfo.SortIndex != objSoftIndexs[i])
                    {
                        objPowerInfo.SortIndex = objSoftIndexs[i];
                        objPowerInfo.SetState(EntityStatus.Modified);
                    }
                    i++;
                }
            }
            int result = 0;
            objBizPowerInfo.ExecuteTransation(() =>
            {
                result = objBizPowerInfo.Batch(objPowerInfoList, false);

                if (IsCheckUserPowerRedis)
                {
                    objBizPowerInfo.StoreAll(objPowerInfoList, PowerVariable.ProviderName, PowerVariable.Db);
                }
            }, true);
            if (result < 0)
            {
                objInvokeResult.ResultCode = "SortFailed";
                objInvokeResult.ResultMessage = "排序异常，请与管理员联系";
                return objInvokeResult;
            }
            objInvokeResult.ResultMessage = "排序成功";
            return objInvokeResult;
        }
        /// <summary>
        /// 权限移动-保存
        /// </summary>
        /// <param name="targetId"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public InvokeResult SaveMove(long targetId, long parentId)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (parentId == targetId)
            {
                objInvokeResult.ResultCode = "SelfMove";
                objInvokeResult.ResultMessage = "无法移动自身";
                return objInvokeResult;
            }
            BizPowerInfo objBizPowerInfo = new BizPowerInfo();
            var objPowerInfoList = objBizPowerInfo.GetList(string.Format("Id in({0},{1})", parentId, targetId));
            if (objPowerInfoList.IsNull())
            {
                objInvokeResult.ResultCode = "PowerInfoListNull";
                objInvokeResult.ResultMessage = "没有获得要操作的权限";
                return objInvokeResult;
            }
            var objParent = objPowerInfoList.FirstOrDefault(c => c.Id == parentId);
            if (objParent == null)
            {
                objInvokeResult.ResultCode = "ParentNull";
                objInvokeResult.ResultMessage = "父权限不存在";
                return objInvokeResult;
            }
            var objTarget = objPowerInfoList.FirstOrDefault(c => c.Id == targetId);
            if (objTarget == null)
            {
                objInvokeResult.ResultCode = "TargetNull";
                objInvokeResult.ResultMessage = "要移动的权限不存在";
                return objInvokeResult;
            }
            if (objTarget.ParentId == objParent.Id)
            {
                objInvokeResult.ResultCode = "AlreadyContains";
                objInvokeResult.ResultMessage = "已经在" + objParent.PowerName + "下，无须移动";
                return objInvokeResult;
            }
            if (objParent.IDPath.Contains(objTarget.IDPath))
            {
                objInvokeResult.ResultCode = "MoveError";
                objInvokeResult.ResultMessage = "无法将父权限移动到子权限下";
                return objInvokeResult;
            }
            List<PowerInfo> objUpdates = new List<PowerInfo>();

            var objTargetParent = objBizPowerInfo.GetRecord(objTarget.ParentId);
            if (objTargetParent != null)
            {
                var objBrothers = objBizPowerInfo.GetList("ParentId=" + objTarget.ParentId);
                //有且只有一个权限，并且是移动的目标权限时，更新移动目标的父权限
                if (objBrothers.Count() == 1)
                {
                    objTargetParent.HasChild = 0;
                    objTargetParent.SetState(EntityStatus.Modified);
                    objUpdates.Add(objTargetParent);
                }
            }

            //更新根节点以及所有子节点
            var objTargetTree = objBizPowerInfo.GetList(objTarget.IDPath.FormatSelf("IDPath like '{0}%'"));
            if (objTargetTree.IsNoNull())
            {
                objTargetTree = objTargetTree.Except(new List<PowerInfo> { objTarget }).ToList();
            }
            objTarget.ParentId = objParent.Id;
            objTarget.Depth = objParent.Depth + 1;
            objTarget.IDPath = objParent.IDPath + objTarget.Id + ",";
            objTarget.SetState(EntityStatus.Modified);
            objUpdates.Add(objTarget);
            SetChildrenUpdate(objTargetTree, objTarget, objUpdates);

            if (objParent.HasChild != 1)
            {
                objParent.HasChild = 1;
                objParent.SetState(EntityStatus.Modified);
                objUpdates.Add(objParent);
            }
            int result = 0;

            objBizPowerInfo.ExecuteTransation(() =>
            {
                result = objBizPowerInfo.Batch(objUpdates, false);

                if (IsCheckUserPowerRedis)
                {
                    objBizPowerInfo.StoreAll(objUpdates, PowerVariable.ProviderName, PowerVariable.Db);
                }
            }, true);

            if (result < 0)
            {
                objInvokeResult.ResultCode = "MoveFailed";
                objInvokeResult.ResultMessage = objTarget.PowerName.FormatSelf("{0}移动失败");
                return objInvokeResult;
            }
            objInvokeResult.ResultMessage = objTarget.PowerName.FormatSelf("{0}移动成功");
            return objInvokeResult;
        }
        /// <summary>
        /// 更新所有子节点
        /// </summary>
        /// <param name="objPowerInfoList"></param>
        /// <param name="objRoot"></param>
        /// <param name="objUpdates"></param>
        void SetChildrenUpdate(IEnumerable<PowerInfo> objPowerInfoList, PowerInfo objRoot, List<PowerInfo> objUpdates)
        {
            if (objPowerInfoList.IsNull())
            {
                return;
            }
            if (objRoot.HasChild == 1)
            {
                var objChildren = objPowerInfoList.Where(c => c.ParentId == objRoot.Id).ToList();
                if (objChildren.IsNoNull())
                {
                    foreach (var objChild in objChildren.OrderBy(c => c.SortIndex))
                    {
                        objChild.Depth = objRoot.Depth + 1;
                        objChild.IDPath = objRoot.IDPath + objChild.Id + ",";
                        objChild.SetState(EntityStatus.Modified);
                        objUpdates.Add(objChild);
                        SetChildrenUpdate(objPowerInfoList, objChild, objUpdates);
                    }
                }
            }
        }

        /// <summary>
        /// 权限复制-保存
        /// </summary>
        /// <param name="targetId"></param>
        /// <param name="parentId"></param>
        /// <param name="copyNumber"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public InvokeResult SaveCopy(long targetId, long parentId, int copyNumber, Action<List<PowerInfo>> action = null)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (copyNumber <= 0)
            {
                objInvokeResult.ResultCode = "CopyNumberNull";
                objInvokeResult.ResultMessage = "请选择复制个数";
                return objInvokeResult;
            }
            if (copyNumber > 10)
            {
                objInvokeResult.ResultCode = "CopyNumberNull";
                objInvokeResult.ResultMessage = "复制个数不能超过10个";
                return objInvokeResult;
            }
            BizPowerInfo objBizPowerInfo = new BizPowerInfo();
            var objPowerInfoList = objBizPowerInfo.GetList(string.Format("Id in({0},{1})", parentId, targetId));
            if (objPowerInfoList.IsNull())
            {
                objInvokeResult.ResultCode = "PowerInfoListNull";
                objInvokeResult.ResultMessage = "没有获得要操作的权限";
                return objInvokeResult;
            }
            var objParent = objPowerInfoList.FirstOrDefault(c => c.Id == parentId);
            if (objParent == null)
            {
                objInvokeResult.ResultCode = "ParentNull";
                objInvokeResult.ResultMessage = "父权限不存在";
                return objInvokeResult;
            }
            var objTarget = objPowerInfoList.FirstOrDefault(c => c.Id == targetId);
            if (objTarget == null)
            {
                objInvokeResult.ResultCode = "TargetNull";
                objInvokeResult.ResultMessage = "要复制的权限不存在";
                return objInvokeResult;
            }
            int result = 0;
            objBizPowerInfo.ExecuteTransation(() =>
            {
                List<PowerInfo> objUpdates = new List<PowerInfo>();
                for (int i = 0; i < copyNumber; i++)
                {
                    PowerInfo objCopy = new PowerInfo();
                    Save(objCopy, objTarget);
                    objCopy.PowerCode = Guid.NewGuid().ToString();
                    objCopy.AreaName = "";
                    objCopy.ControllerName = "";
                    objCopy.ActionName = "";
                    objCopy.CreateDate = DateTime.Now;

                    objCopy.ParentId = objParent.Id;
                    objCopy.HasChild = 1;
                    objCopy.Depth = objParent.Depth + 1;
                    objCopy.Id = objBizPowerInfo.Add(objTarget);
                    objCopy.IDPath = objParent.IDPath + objCopy.Id + ",";
                    objCopy.SortIndex = objCopy.Id;
                    objCopy.SetState(EntityStatus.Modified);
                    objUpdates.Add(objCopy);
                }

                if (action != null)
                {
                    action(objUpdates);
                }

                if (objParent.HasChild != 1)
                {
                    objParent.HasChild = 1;
                    objParent.SetState(EntityStatus.Modified);
                    objUpdates.Add(objParent);
                }

                result = objBizPowerInfo.Batch(objUpdates, false);

                if (IsCheckUserPowerRedis)
                {
                    objBizPowerInfo.StoreAll(objUpdates, PowerVariable.ProviderName, PowerVariable.Db);
                }
            });
            if (result < 0)
            {
                objInvokeResult.ResultCode = "CopyFailed";
                objInvokeResult.ResultMessage = objTarget.PowerName.FormatSelf("{0}复制失败");
                return objInvokeResult;
            }
            objInvokeResult.ResultMessage = objTarget.PowerName.FormatSelf("{0}复制成功");
            return objInvokeResult;
        }
        void Save(PowerInfo objTarget, PowerInfo objProvide)
        {
            objTarget.PowerName = objProvide.PowerName.CutWord(64);
            objTarget.ParentId = objProvide.ParentId;
            objTarget.AreaName = objProvide.AreaName.CutWord(64);
            objTarget.ControllerName = objProvide.ControllerName.CutWord(64);
            objTarget.ActionName = objProvide.ActionName.CutWord(64);
            objTarget.LinkUrl = objProvide.LinkUrl.CutWord(256);
            objTarget.PowerType = objProvide.PowerType;
            objTarget.Position = objProvide.Position;
            objTarget.Execution = objProvide.Execution.CutWord(64);
            objTarget.Icon = objProvide.Icon.CutWord(64);
            objTarget.IsDisplay = objProvide.IsDisplay;
        }
    }
}
